package p10.code;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Semaphore;

/**
 * 使用信号量包装HashSet使其变为有界的阻塞Set
 * @param <T>
 */
public class BoundedHashSet<T> {

    //声明一个set
    private final Set<T> set;
    //声明信号量,此信号量用来限制Set的长度
    private final Semaphore sem;

    //初始化set和信号量
    public BoundedHashSet(int bound) {
        this.set = Collections.synchronizedSet(new HashSet<T>());
        sem = new Semaphore(bound);
    }

    //定义添加元素的操作
    public boolean add(T o) throws InterruptedException {
        //获得许可，获取到就接着往下执行，否则阻塞
        sem.acquire();
        boolean wasAdded = false;
        try{
            wasAdded = set.add(o);//添加操作
            return wasAdded;
        }finally{
            if(!wasAdded){
                sem.release();//如果添加失败，释放许可
            }
        }
    }

    //定义删除元素的操作
    public boolean remove(T o) {
        boolean wasRemoved = set.remove(o);//进行删除操作
        if(wasRemoved)
            sem.release();//如果删除成功，释放许可
        return wasRemoved;
    }

    public static void main(String[] args) throws InterruptedException {
        BoundedHashSet<String> boundedHashSet = new BoundedHashSet<>(2);
        for(int i=0;i<3;i++){
            boolean success = boundedHashSet.add(""+i);
            if(success) System.out.println("添加成功");
            else System.out.println("添加失败");
        }
    }

}
